package school;

class Shape {

    /**
     * 8. 初始创建好的字段方法
     */
    private int field = printInit("@Father Field");

    private void method() {
    }

    /**
     * 7. 构造对象(实例化) 创建字段、方法 完成后发现自己已经是祖宗了（其实往上还有 Object，但这里忽略）
     */
    Shape() {
        /** 9. 执行构造函数中的语句 */
        System.out.println("@Father Constructor: i = " + i + ", j = " + j);
        j = 5;
    }

    /**
     * 2. 顺序加载父类的资源 注意由于赋值是右边赋值给左边，所以实际上是 printInit 先加载完毕
     */
    private static int i;
    protected static int j = 10;
    private static int x1 = printInit("@Father Static Source: private Shape.x1 initialized Static Source");

    static int printInit(String s) {
        System.out.println(s);
        return ++i;
    }
}

public class Circle extends Shape {
    /** 10. 初始化字段和方法 */
    int k = printInit("@Son Field: Circle.k initialized");

    /**
     * 6. 进入构造函数，开始创建对象(实例化) 分配存储空间 -> 创建字段和方法(还没有赋值，但已经存在) 先执行 super() 父类的构造
     */
    public Circle() {
        /** 11. 执行构造函数中的语句 */
        System.out.println("@Son Constructor: k = " + k);
        System.out.println("j = " + j);
        System.out.println("x2 = " + x2);
    }

    /**
     * 3. 父类的资源加载完后，子类加载资源 类的资源就是静态资源，对象的资源就是普通字段/方法 main 函数也是静态资源！
     */
    public static int x2 = printInit("@Son Static Source: public Circle.x2 initialized Static Sourcce");

    /**
     * 1. 要加载 main 函数(子类的static资源)就要先加载 Circle.class 发现有父类 Shape，所以先加载 Shape.class
     */

    public static void main(String[] args) {
        /** 4. 执行 main 函数 */
        System.out.println("@Son Static Source: main method");
        /** 5. 遇到 new Circle() 要调用构造函数 */
        Circle b = new Circle();
        /** 12. b 对象构造完成继续下一条语句 */
        System.out.println("@Keep Going in main: b.k=" + b.k);
    }
}